package hyperlinkyclassic;

import com.google.wave.api.*;
import java.util.*;

@SuppressWarnings("serial")
public class HyperLinkyClassicServlet extends AbstractRobotServlet {

	Triggers triggers = new Triggers();

	@Override
	public void processEvents(RobotMessageBundle bundle) {
		Wavelet wavelet = bundle.getWavelet();

		if (bundle.wasSelfAdded()) {
			Blip blip = wavelet.appendBlip();
			TextView textView = blip.getDocument();
			textView.append("Hi there, I'm HyperLinky Classic! Type h_blip for help.");
		}
        
		for (Event e: bundle.getEvents()) {
			if(e.getType() == EventType.BLIP_SUBMITTED) {
				Blip theBlip = e.getBlip();
				// TextView textView = theBlip.getDocument();
				String modBy = e.getModifiedBy();
				if(!modBy.equals("hyperlinkyclassic@appspot.com") && !modBy.equals("panda@a.gwave.com") && !modBy.equals("spelly@a.gwave.com")) {
					// textView.append("This has been edited by "  +modBy);
					processBlip(theBlip, wavelet);
				}
			}
		}
	}
		
	private void processBlip(Blip blip, Wavelet wavelet){
		TextView doc = blip.getDocument();
		String blipContent = doc.getText();	//content of the blip
		List<TriggerEntry> posn = new ArrayList<TriggerEntry>();	//List of positions
		//Locate every Trigger replacement
		for(Trigger trigger : triggers.triggerList){
			int i = 0, j = 0;
			String delimiter = "";
			while (blipContent.indexOf(trigger.getText(), i) != -1){                            
				i = blipContent.indexOf(trigger.getText(), i);	// Update to the position
				switch(blipContent.charAt(i+trigger.getText().length())) { // if there is no (,', or ", assume only one word!!
					case '(':	delimiter = ")";
								break;
					case '\"':	delimiter = "\"";
								break;
					case '\'':	delimiter = "\'";
								break;
					default:	delimiter = "";
								break;
				}
				if(delimiter.length() == 0) { // there is no delimiter, look for whitespace??
					j = blipContent.indexOf(" ", i);
					if(j == -1)
						j = blipContent.indexOf("\n", i);
					if(j == -1)
						j = blipContent.length();
				}
				else {
					j = blipContent.indexOf(delimiter, i + trigger.getText().length() + 2) + 1;	// Find end of the trigger
				}
				// doc.append("\ndelimiter is: " + delimiter + "\ni is: " + i + "\nj is: " + j + "\n" + blipContent.substring(i, j));
				if(j > (i + trigger.getText().length())) // only add if there is an interval!
					posn.add(new TriggerEntry(i, delimiter, blipContent.substring(i, j) , trigger));	//Add entry to list
				i++; //Increment to move on
			}
		}
		// Organize the list of entries so deletes etc. don't override each other
		Collections.sort(posn);
		Collections.reverse(posn);

		//Insert the searchLink into the blip
		// ugly hack variables
		int i = 0;
		int offset = 0;
		for (TriggerEntry entry : posn) {
			if(entry.getHTMLEncodedSearchText().length() == 0) { // if there's nothing to link...
				// do nothing!!
			}
			else if (entry.getTrigger().getText() == "h_" && entry.getSearchText().equals("blip")) {
				//Blip helpBlip = wavelet.appendBlip();
				Blip helpBlip = blip.createChild();
				TextView textView = helpBlip.getDocument();
				textView.append(triggers.toString());
			}
			else {
				// begin ridiculous hack to fix google's annotation problems
				offset = 0;
				for(int j = 1+i; j < posn.size(); j++) {	// iterate from last to first
					//offset += posn.get(j).getTrigger().getText().length()+(posn.get(j).getDelimiter().length()*2);
					offset += posn.get(j).getText().length() - posn.get(j).getSearchText().length();
				}
				i++;
				// end ridiculous hack
				doc.delete(new Range(entry.getStartPos(), (entry.getStartPos() + entry.getText().length()) )); //Delete the trigger
				doc.insert(entry.getStartPos(), entry.getSearchText());
				if(blipContent.length() == entry.getStartPos()+entry.getText().length())	// if it's @ the end of the blip...
					doc.append(" ");	// add space to the end
				// doc.insert(entry.getStartPos()+entry.getSearchText().length(), " ");	// ... add a space to facilitate later edits sans-linkage
				doc.setAnnotation(new Range(entry.getStartPos()+offset, entry.getStartPos()+entry.getSearchText().length()+offset), "link/manual", entry.getTrigger().getSearchLink() + entry.getHTMLEncodedSearchText()/* + i + "," + offset*/);
				// doc.delete(new Range(entry.getStartPos()+entry.getSearchText().length(),entry.getStartPos()+entry.getSearchText().length()+1));
			}
		}
	}
}
